﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Uint8 = System.Byte;
using Uint32 = System.UInt32;
using Sint32 = System.Int32;
using Uint16 = System.UInt16;
using System;

public struct s
{
    public Uint32 width;
    public Uint32 height;
    public Uint32 bit;
}

public enum SDL_Keycode
{
    SDLK_UNKNOWN = 0,

    SDLK_RETURN = '\r',
    //SDLK_ESCAPE = '\033',
    SDLK_ESCAPE = '\0',
    SDLK_BACKSPACE = '\b',
    SDLK_TAB = '\t',
    SDLK_SPACE = ' ',
    SDLK_EXCLAIM = '!',
    SDLK_QUOTEDBL = '"',
    SDLK_HASH = '#',
    SDLK_PERCENT = '%',
    SDLK_DOLLAR = '$',
    SDLK_AMPERSAND = '&',
    SDLK_QUOTE = '\'',
    SDLK_LEFTPAREN = '(',
    SDLK_RIGHTPAREN = ')',
    SDLK_ASTERISK = '*',
    SDLK_PLUS = '+',
    SDLK_COMMA = ',',
    SDLK_MINUS = '-',
    SDLK_PERIOD = '.',
    SDLK_SLASH = '/',
    SDLK_0 = '0',
    SDLK_1 = '1',
    SDLK_2 = '2',
    SDLK_3 = '3',
    SDLK_4 = '4',
    SDLK_5 = '5',
    SDLK_6 = '6',
    SDLK_7 = '7',
    SDLK_8 = '8',
    SDLK_9 = '9',
    SDLK_COLON = ':',
    SDLK_SEMICOLON = ';',
    SDLK_LESS = '<',
    SDLK_EQUALS = '=',
    SDLK_GREATER = '>',
    SDLK_QUESTION = '?',
    SDLK_AT = '@',
    /*
       Skip uppercase letters
     */
    SDLK_LEFTBRACKET = '[',
    SDLK_BACKSLASH = '\\',
    SDLK_RIGHTBRACKET = ']',
    SDLK_CARET = '^',
    SDLK_UNDERSCORE = '_',
    SDLK_BACKQUOTE = '`',
    SDLK_a = 'a',
    SDLK_b = 'b',
    SDLK_c = 'c',
    SDLK_d = 'd',
    SDLK_e = 'e',
    SDLK_f = 'f',
    SDLK_g = 'g',
    SDLK_h = 'h',
    SDLK_i = 'i',
    SDLK_j = 'j',
    SDLK_k = 'k',
    SDLK_l = 'l',
    SDLK_m = 'm',
    SDLK_n = 'n',
    SDLK_o = 'o',
    SDLK_p = 'p',
    SDLK_q = 'q',
    SDLK_r = 'r',
    SDLK_s = 's',
    SDLK_t = 't',
    SDLK_u = 'u',
    SDLK_v = 'v',
    SDLK_w = 'w',
    SDLK_x = 'x',
    SDLK_y = 'y',
    SDLK_z = 'z',

    //SDLK_KP_1 = SDL.SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_1),
    //SDLK_KP_2 = SDL.SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_2),
    //SDLK_KP_3 = SDL.SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_3),
    //SDLK_KP_4 = SDL.SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_4),
    //SDLK_KP_5 = SDL.SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_5),
    //SDLK_KP_6 = SDL.SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_6),
    //SDLK_KP_7 = SDL.SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_7),
    //SDLK_KP_8 = SDL.SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_8),
    //SDLK_KP_9 = SDL.SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_9),
    //SDLK_KP_0 = SDL.SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_0),

    SDLK_KP_1 = SDL_Scancode.SDL_SCANCODE_KP_1 |(1<<30),
    SDLK_KP_2 = SDL_Scancode.SDL_SCANCODE_KP_2 | (1 << 30),
    SDLK_KP_3 = SDL_Scancode.SDL_SCANCODE_KP_3 | (1 << 30),
    SDLK_KP_4 = SDL_Scancode.SDL_SCANCODE_KP_4 | (1 << 30),
    SDLK_KP_5 = SDL_Scancode.SDL_SCANCODE_KP_5 | (1 << 30),
    SDLK_KP_6 = SDL_Scancode.SDL_SCANCODE_KP_6 | (1 << 30),
    SDLK_KP_7 = SDL_Scancode.SDL_SCANCODE_KP_7 | (1 << 30),
    SDLK_KP_8 = SDL_Scancode.SDL_SCANCODE_KP_8 | (1 << 30),
    SDLK_KP_9 = SDL_Scancode.SDL_SCANCODE_KP_9 | (1 << 30),
    SDLK_KP_0 = SDL_Scancode.SDL_SCANCODE_KP_0 | (1 << 30),

    SDLK_RIGHT = SDL_Scancode.SDL_SCANCODE_RIGHT | (1 << 30),
    SDLK_LEFT = SDL_Scancode.SDL_SCANCODE_LEFT | (1 << 30),
    SDLK_DOWN = SDL_Scancode.SDL_SCANCODE_DOWN | (1 << 30),
    SDLK_UP = SDL_Scancode.SDL_SCANCODE_UP | (1 << 30),

    SDLK_KP_ENTER = SDL_Scancode.SDL_SCANCODE_KP_ENTER | (1 << 30),
}

public enum SDL_Scancode
{
    SDL_SCANCODE_KP_DIVIDE = 84,
    SDL_SCANCODE_KP_MULTIPLY = 85,
    SDL_SCANCODE_KP_MINUS = 86,
    SDL_SCANCODE_KP_PLUS = 87,
    SDL_SCANCODE_KP_ENTER = 88,
    SDL_SCANCODE_KP_1 = 89,
    SDL_SCANCODE_KP_2 = 90,
    SDL_SCANCODE_KP_3 = 91,
    SDL_SCANCODE_KP_4 = 92,
    SDL_SCANCODE_KP_5 = 93,
    SDL_SCANCODE_KP_6 = 94,
    SDL_SCANCODE_KP_7 = 95,
    SDL_SCANCODE_KP_8 = 96,
    SDL_SCANCODE_KP_9 = 97,
    SDL_SCANCODE_KP_0 = 98,
    SDL_SCANCODE_KP_PERIOD = 99,

    SDL_SCANCODE_RIGHT = 79,
    SDL_SCANCODE_LEFT = 80,
    SDL_SCANCODE_DOWN = 81,
    SDL_SCANCODE_UP = 82,
}

public enum SDL_WindowFlags
{
    /* !!! FIXME: change this to name = (1<<x). */
    SDL_WINDOW_FULLSCREEN = 0x00000001,         /**< fullscreen window */
    SDL_WINDOW_OPENGL = 0x00000002,             /**< window usable with OpenGL context */
    SDL_WINDOW_SHOWN = 0x00000004,              /**< window is visible */
    SDL_WINDOW_HIDDEN = 0x00000008,             /**< window is not visible */
    SDL_WINDOW_BORDERLESS = 0x00000010,         /**< no window decoration */
    SDL_WINDOW_RESIZABLE = 0x00000020,          /**< window can be resized */
    SDL_WINDOW_MINIMIZED = 0x00000040,          /**< window is minimized */
    SDL_WINDOW_MAXIMIZED = 0x00000080,          /**< window is maximized */
    SDL_WINDOW_INPUT_GRABBED = 0x00000100,      /**< window has grabbed input focus */
    SDL_WINDOW_INPUT_FOCUS = 0x00000200,        /**< window has input focus */
    SDL_WINDOW_MOUSE_FOCUS = 0x00000400,        /**< window has mouse focus */
    SDL_WINDOW_FULLSCREEN_DESKTOP = (SDL_WINDOW_FULLSCREEN | 0x00001000),
    SDL_WINDOW_FOREIGN = 0x00000800,            /**< window not created by SDL */
    SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000,      /**< window should be created in high-DPI mode if supported.
                                                     On macOS NSHighResolutionCapable must be set true in the
                                                     application's Info.plist for this to have any effect. */
    SDL_WINDOW_MOUSE_CAPTURE = 0x00004000,      /**< window has mouse captured (unrelated to INPUT_GRABBED) */
    SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000,      /**< window should always be above others */
    SDL_WINDOW_SKIP_TASKBAR = 0x00010000,      /**< window should not be added to the taskbar */
    SDL_WINDOW_UTILITY = 0x00020000,      /**< window should be treated as a utility window */
    SDL_WINDOW_TOOLTIP = 0x00040000,      /**< window should be treated as a tooltip */
    SDL_WINDOW_POPUP_MENU = 0x00080000,      /**< window should be treated as a popup menu */
    SDL_WINDOW_VULKAN = 0x10000000       /**< window usable for Vulkan surface */
}

public enum SDL_EventType
{
    SDL_FIRSTEVENT = 0,     /**< Unused (do not remove) */

    /* Application events */
    SDL_QUIT = 0x100, /**< User-requested quit */

    /* These application events have special meaning on iOS, see README-ios.md for details */
    SDL_APP_TERMINATING,        /**< The application is being terminated by the OS
                                     Called on iOS in applicationWillTerminate()
                                     Called on Android in onDestroy()
                                */
    SDL_APP_LOWMEMORY,          /**< The application is low on memory, free memory if possible.
                                     Called on iOS in applicationDidReceiveMemoryWarning()
                                     Called on Android in onLowMemory()
                                */
    SDL_APP_WILLENTERBACKGROUND, /**< The application is about to enter the background
                                     Called on iOS in applicationWillResignActive()
                                     Called on Android in onPause()
                                */
    SDL_APP_DIDENTERBACKGROUND, /**< The application did enter the background and may not get CPU for some time
                                     Called on iOS in applicationDidEnterBackground()
                                     Called on Android in onPause()
                                */
    SDL_APP_WILLENTERFOREGROUND, /**< The application is about to enter the foreground
                                     Called on iOS in applicationWillEnterForeground()
                                     Called on Android in onResume()
                                */
    SDL_APP_DIDENTERFOREGROUND, /**< The application is now interactive
                                     Called on iOS in applicationDidBecomeActive()
                                     Called on Android in onResume()
                                */

    /* Display events */
    SDL_DISPLAYEVENT = 0x150,  /**< Display state change */

    /* Window events */
    SDL_WINDOWEVENT = 0x200, /**< Window state change */
    SDL_SYSWMEVENT,             /**< System specific event */

    /* Keyboard events */
    SDL_KEYDOWN = 0x300, /**< Key pressed */
    SDL_KEYUP,                  /**< Key released */
    SDL_TEXTEDITING,            /**< Keyboard text editing (composition) */
    SDL_TEXTINPUT,              /**< Keyboard text input */
    SDL_KEYMAPCHANGED,          /**< Keymap changed due to a system event such as an
                                     input language or keyboard layout change.
                                */

    /* Mouse events */
    SDL_MOUSEMOTION = 0x400, /**< Mouse moved */
    SDL_MOUSEBUTTONDOWN,        /**< Mouse button pressed */
    SDL_MOUSEBUTTONUP,          /**< Mouse button released */
    SDL_MOUSEWHEEL,             /**< Mouse wheel motion */

    /* Joystick events */
    SDL_JOYAXISMOTION = 0x600, /**< Joystick axis motion */
    SDL_JOYBALLMOTION,          /**< Joystick trackball motion */
    SDL_JOYHATMOTION,           /**< Joystick hat position change */
    SDL_JOYBUTTONDOWN,          /**< Joystick button pressed */
    SDL_JOYBUTTONUP,            /**< Joystick button released */
    SDL_JOYDEVICEADDED,         /**< A new joystick has been inserted into the system */
    SDL_JOYDEVICEREMOVED,       /**< An opened joystick has been removed */

    /* Game controller events */
    SDL_CONTROLLERAXISMOTION = 0x650, /**< Game controller axis motion */
    SDL_CONTROLLERBUTTONDOWN,          /**< Game controller button pressed */
    SDL_CONTROLLERBUTTONUP,            /**< Game controller button released */
    SDL_CONTROLLERDEVICEADDED,         /**< A new Game controller has been inserted into the system */
    SDL_CONTROLLERDEVICEREMOVED,       /**< An opened Game controller has been removed */
    SDL_CONTROLLERDEVICEREMAPPED,      /**< The controller mapping was updated */

    /* Touch events */
    SDL_FINGERDOWN = 0x700,
    SDL_FINGERUP,
    SDL_FINGERMOTION,

    /* Gesture events */
    SDL_DOLLARGESTURE = 0x800,
    SDL_DOLLARRECORD,
    SDL_MULTIGESTURE,

    /* Clipboard events */
    SDL_CLIPBOARDUPDATE = 0x900, /**< The clipboard changed */

    /* Drag and drop events */
    SDL_DROPFILE = 0x1000, /**< The system requests a file open */
    SDL_DROPTEXT,                 /**< text/plain drag-and-drop event */
    SDL_DROPBEGIN,                /**< A new set of drops is beginning (NULL filename) */
    SDL_DROPCOMPLETE,             /**< Current set of drops is now complete (NULL filename) */

    /* Audio hotplug events */
    SDL_AUDIODEVICEADDED = 0x1100, /**< A new audio device is available */
    SDL_AUDIODEVICEREMOVED,        /**< An audio device has been removed. */

    /* Sensor events */
    SDL_SENSORUPDATE = 0x1200,     /**< A sensor was updated */

    /* Render events */
    SDL_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
    SDL_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */

    /** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use,
     *  and should be allocated with SDL_RegisterEvents()
     */
    SDL_USEREVENT = 0x8000,

    /**
     *  This last event is only for bounding internal arrays
     */
    SDL_LASTEVENT = 0xFFFF
}

public unsafe class SDL : Uc
{
    public static long SDLK_SCANCODE_MASK= (1 << 30);
    public static int SDL_SCANCODE_TO_KEYCODE(int X)
    {
        return (int)((X | SDLK_SCANCODE_MASK));
    }
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    

    public static bool SDL_WaitEvent(SDL_Event e)
    {
        return false;
    }

    public static SDL_Window SDL_CreateWindow(string title,uint x, uint y, int w,int h, SDL_WindowFlags flags)
    {
        return new SDL_Window() { title =title ,w=w,h=h};
    }

    public static string SDL_GetError()
    {
        return "Error";
    }

    public static void SDL_RemoveTimer(SDL_TimerID timeId)
    {

    }
    public delegate uint th2(uint interval, object param);
    public static SDL_TimerID SDL_AddTimer(ushort  time,th2 th,object obj )
    {
        return new SDL_TimerID(time);
    }

    public static SDL_Surface SDL_GetWindowSurface(SDL_Window window)
    {
        return new SDL_Surface() { window =window };
    }

    public static int SDL_LockSurface(SDL_Surface surface)
    {
        return 0;
    }

    public static void SDL_UnlockSurface(SDL_Surface S)
    {
        
    }

    public static int SDL_UpdateWindowSurface(SDL_Window window)
    {
        return 0;
    }

    public static uint* SDL_MapRGB(SDL_PixelFormat* format,uint r,uint g,uint b)
    {
        return null;
    }

    public static int SDL_SWSURFACE = 0;        /**< Just here for compatibility */
    public static int SDL_PREALLOC = 0x00000001;  /**< Surface uses preallocated memory */
    public static int SDL_RLEACCEL = 0x00000002;  /**< Surface is RLE encoded */
    public static int SDL_DONTFREE = 0x00000004;  /**< Surface is referenced internally */
    public static int SDL_SIMD_ALIGNED = 0x00000008;  /**< Surface uses aligned memory */

    public static bool SDL_MUSTLOCK(SDL_Surface S)
    {
        return (((S).flags & SDL_RLEACCEL) != 0);
    }

    public static void LOG(string v, IntPtr name )
    {
        Console.Write(v, new string((sbyte*)name));
    }

    public static void LOG(string v, IntPtr name, object nptr = null, uint add = 0, uint x = 0, uint y = 0, uint z = 0,uint v1=0,uint b=0)
    {
        print(string.Format(v, new string((sbyte*)name), nptr, add,x,y,z));
    }

    public static void LOG(string v, IntPtr name, uint nptr = 0, byte* add = null, uint x = 0, uint y = 0, uint z = 0, uint v1 = 0, uint b = 0,uint a=0,uint c=0)
    {
        Console.Write(v);
    }

    public static void LOG(string v, string name="", object  nptr=null, sbyte* str=null, uint x = 0, uint y = 0)
    {
        Console.Write(v,name);
    }

    public static void LOG(string v, string name = "", object nptr = null, uint str = 0)
    {
        Console.Write(v, name);
    }

    public static void LOG(string v)
    {
        Console.Write(v);
    }

    public static void LOG(string v,sbyte * p)
    {
        Console.Write(v);
    }

    public static void LOG(string v, string name, uint pcText, sbyte* str, uint x, uint y, uint r, uint g, uint b, uint is_unicode, uint font)
    {
        Console.Write(v,name);
    }

    public static uint SDL_WINDOWPOS_UNDEFINED = 0 | 0x1FFF0000u;
}

public unsafe struct SDL_PixelFormat
{

}

public unsafe class SDL_Surface
{
   public SDL_Window window;
   public SDL_PixelFormat* format;    /**< Read-only */
    public Uint32 flags;               /**< Read-only */

    public int w, h;                   /**< Read-only */
    public int pitch;                  /**< Read-only */
    public void* pixels;               /**< Read-write */
}



public class SDL_Event
{
    public SDL_EventType type; /**< Event type, shared with all events */
    public SDL_KeyboardEvent key;/**< Keyboard event data */
    public SDL_MouseMotionEvent motion;    /**< Mouse motion event data */
}

public struct SDL_MouseMotionEvent
{
    public Uint32 type;        /**< ::SDL_MOUSEMOTION */
    public Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
    public Uint32 windowID;    /**< The window with mouse focus, if any */
    public Uint32 which;       /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
    public Uint32 state;       /**< The current button state */
    public Sint32 x;           /**< X coordinate, relative to window */
    public Sint32 y;           /**< Y coordinate, relative to window */
    public Sint32 xrel;        /**< The relative motion in the X direction */
    public Sint32 yrel;        /**< The relative motion in the Y direction */
}

public struct SDL_KeyboardEvent
{
    public Uint32 type;        /**< ::SDL_KEYDOWN or ::SDL_KEYUP */
    public Uint32 timestamp;   /**< In milliseconds, populated using SDL_GetTicks() */
    public Uint32 windowID;    /**< The window with keyboard focus, if any */
    public Uint8 state;        /**< ::SDL_PRESSED or ::SDL_RELEASED */
    public Uint8 repeat;       /**< Non-zero if this is a key repeat */
    public Uint8 padding2;
    public Uint8 padding3;
    public SDL_Keysym keysym;  /**< The key that was pressed or released */
}

public struct SDL_Keysym
{
    public SDL_Scancode scancode;      /**< SDL physical key code - see ::SDL_Scancode for details */
    public SDL_Keycode sym;            /**< SDL virtual key code - see ::SDL_Keycode for details */
    public Uint16 mod;                 /**< current key modifiers */
    public Uint32 unused;
}

//public enum SDL_Scancode
//{

//}

public class SDL_Window
{
    public string title;
    public int h;
    public int w;

}

public class SDL_TimerID 
{
    public int id;
    public static implicit operator SDL_TimerID(int id)
    {
        return new SDL_TimerID (id);
    }

    public SDL_TimerID (int Id)
    {
        id = Id;
    }
}

public class Environment
{
    public static void Exit(int i)
    {

    }
}
